package com.ruoyi.system.service.impl;

import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysProduct;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanValidators;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;

import javax.validation.Validator;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SysProductServiceImpl implements ISysProductService
{
    private static final Logger log = LoggerFactory.getLogger(SysProductServiceImpl.class);

    @Autowired
    private SysProductMapper productMapper;

    @Autowired
    private SysPostMapper postMapper;

    @Autowired
    private SysProductPostMapper productPostMapper;

    @Autowired
    private ISysDeptService deptService;

    @Autowired
    private SysPurposeMapper purposeMapper;

    @Autowired
    private SysProductPurposeMapper productPurposeMapper;


    @Autowired
    protected Validator validator;

    @Override
    public List<SysProduct> selectProductList(SysProduct product) {

        List<SysProduct> sysProducts = productMapper.selectProductList(product);
        sysProducts.forEach(sysProduct -> {
            List<SysPost> list = postMapper.selectPostsByProductName(sysProduct.getProductName());
            List<SysPurpose> list01 = purposeMapper.selectPurposesByProductName(sysProduct.getProductName());
//            if (CollectionUtils.isEmpty(list))
//            {
//                return EMPTY;
//            }
            List<String> arr = list.stream().map(SysPost::getPostName).collect(Collectors.toList());
            List<String> arr01 = list01.stream().map(SysPurpose::getPurposeName).collect(Collectors.toList());
            String postNames = String.join(",", arr);
            String purposeNames = String.join(",", arr01);
            Long[] array = postMapper.selectPostListByProductId(sysProduct.getProductId()).toArray(new Long[0]);
            Long[] array01 = purposeMapper.selectPurposeListByProductId(sysProduct.getProductId()).toArray(new Long[0]);
            sysProduct.setPostIds(array);
            sysProduct.setPurposeIds(array01);
            sysProduct.setPostNames(postNames);
            sysProduct.setPurposeNames(purposeNames);
        });



        return sysProducts;
    }

    @Override
    @DataScope(deptAlias = "d", userAlias = "p")
    public List<SysProduct> selectAllocatedList(SysProduct product) {
        return productMapper.selectAllocatedList(product);
    }

    @Override
    @DataScope(deptAlias = "d", userAlias = "p")
    public List<SysProduct> selectUnallocatedList(SysProduct product) {
        return productMapper.selectUnallocatedList(product);
    }

    @Override
    public SysProduct selectProductByProductName(String productName) {
        return productMapper.selectProductByProductName(productName);
    }

    @Override
    public SysProduct selectProductByColor(String color) {
        return productMapper.selectProductByColor(color);
    }

    @Override
    public SysProduct selectProductById(Long productId) {
        SysProduct productDetail = productMapper.selectProductById(productId);
        List<SysPost> list = postMapper.selectPostsByProductName(productDetail.getProductName());
        List<SysPurpose> list01 = purposeMapper.selectPurposesByProductName(productDetail.getProductName());
//            if (CollectionUtils.isEmpty(list))
//            {
//                return EMPTY;
//            }
        List<String> arr = list.stream().map(SysPost::getPostName).collect(Collectors.toList());
        List<String> arr01 = list01.stream().map(SysPurpose::getPurposeName).collect(Collectors.toList());
        String postNames = String.join(",", arr);
        String purposeNames = String.join(",", arr01);
        Long[] array = postMapper.selectPostListByProductId(productDetail.getProductId()).toArray(new Long[0]);
        Long[] array01 = purposeMapper.selectPurposeListByProductId(productDetail.getProductId()).toArray(new Long[0]);
        productDetail.setPostIds(array);
        productDetail.setPurposeIds(array01);
        productDetail.setPostNames(postNames);
        productDetail.setPurposeNames(purposeNames);
        return productDetail;
    }

    @Override
    public String selectProductPostGroup(String productName) {
        List<SysPost> list = postMapper.selectPostsByProductName(productName);
        if (CollectionUtils.isEmpty(list))
        {
            return StringUtils.EMPTY;
        }
        return list.stream().map(SysPost::getPostName).collect(Collectors.joining(","));
    }

    @Override
    public boolean checkProductNameUnique(SysProduct product) {
        Long productId = StringUtils.isNull(product.getProductId()) ? -1L : product.getProductId();
        SysProduct info = productMapper.checkProductNameUnique(product.getProductName());
        if (StringUtils.isNotNull(info) && info.getProductId().longValue() != productId.longValue())
        {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    @Transactional
    public int insertProduct(SysProduct product) {
        // 新增用户信息
        int rows = productMapper.insertProduct(product);
        // 新增产品材质关联
        insertProductPost(product);
        insertProductPurpose(product);
        return rows;
    }

    @Override
    @Transactional
    public int updateProduct(SysProduct product) {
        Long productId = product.getProductId();
        // 删除用户与岗位关联
        productPostMapper.deleteProductPostByProductId(productId);
        productPurposeMapper.deleteProductPurposeByProductId(productId);
        // 新增用户与岗位管理
        insertProductPost(product);
        insertProductPurpose(product);
        return productMapper.updateProduct(product);
    }

    @Override
    public int updateProductStatus(SysProduct product) {
        return productMapper.updateProduct(product);
    }

    @Override
    public int updateProductProfile(SysProduct product) {
        return productMapper.updateProduct(product);
    }

    @Override
    public boolean updateProductAvatar(String productName, String avatar) {
        return productMapper.updateProductAvatar(productName, avatar) > 0;
    }

    /**
     * 新增产品材质信息
     *
     * @param product 用户对象
     */
    public void insertProductPost(SysProduct product)
    {
        Long[] posts = product.getPostIds();
        if (StringUtils.isNotEmpty(posts))
        {
            // 新增用户与岗位管理
            List<SysProductPost> list = new ArrayList<SysProductPost>(posts.length);
            for (Long postId : posts)
            {
                SysProductPost up = new SysProductPost();
                up.setProductId(product.getProductId());
                up.setPostId(postId);
                list.add(up);
            }
            productPostMapper.batchProductPost(list);
        }
    }

    public void insertProductPurpose(SysProduct product)
    {
        Long[] purposes = product.getPurposeIds();
        if (StringUtils.isNotEmpty(purposes))
        {
            // 新增用户与岗位管理
            List<SysProductPurpose> list = new ArrayList<SysProductPurpose>(purposes.length);
            for (Long purposeId : purposes)
            {
                SysProductPurpose up = new SysProductPurpose();
                up.setProductId(product.getProductId());
                up.setPurposeId(purposeId);
                list.add(up);
            }
            productPurposeMapper.batchProductPurpose(list);
        }
    }

    @Override
    @Transactional
    public int deleteProductById(Long productId) {
        // 删除产品与材质表
        productPostMapper.deleteProductPostByProductId(productId);
        productPurposeMapper.deleteProductPurposeByProductId(productId);
        return productMapper.deleteProductById(productId);
    }

    @Override
    @Transactional
    public int deleteProductByIds(Long[] productIds) {
        // 删除产品与材质关联
        productPostMapper.deleteProductPost(productIds);
        productPurposeMapper.deleteProductPurpose(productIds);
        return productMapper.deleteProductByIds(productIds);
    }

    @Override
    public String importProduct(List<SysProduct> productList, Boolean isUpdateSupport, String operName) {
        if (StringUtils.isNull(productList) || productList.size() == 0)
        {
            throw new ServiceException("导入产品数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (SysProduct product : productList)
        {
            try
            {
                // 验证是否存在这个用户
                SysProduct p = productMapper.selectProductByProductName(product.getProductName());
                if (StringUtils.isNull(p))
                {
                    BeanValidators.validateWithException(validator, product);
                    deptService.checkDeptDataScope(product.getDeptId());
                    product.setCreateBy(operName);
                    productMapper.insertProduct(product);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、产品 " + product.getProductName() + " 导入成功");
                }
                else if (isUpdateSupport)
                {
                    BeanValidators.validateWithException(validator, product);
                    deptService.checkDeptDataScope(product.getDeptId());
                    product.setProductId(p.getProductId());
                    product.setUpdateBy(operName);
                    productMapper.updateProduct(product);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、产品 " + product.getProductName() + " 更新成功");
                }
                else
                {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、产品 " + product.getProductName() + " 已存在");
                }
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/>" + failureNum + "、产品 " + product.getProductName() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    @Override
    public List<SysProduct> selectAll() {
        List<SysProduct> sysProducts =productMapper.selectAll();
        sysProducts.forEach(sysProduct -> {
            List<SysPost> list = postMapper.selectPostsByProductName(sysProduct.getProductName());
            List<SysPurpose> list01 = purposeMapper.selectPurposesByProductName(sysProduct.getProductName());
//            if (CollectionUtils.isEmpty(list))
//            {
//                return EMPTY;
//            }
            List<String> arr = list.stream().map(SysPost::getPostName).collect(Collectors.toList());
            List<String> arr01 = list01.stream().map(SysPurpose::getPurposeName).collect(Collectors.toList());
            String postNames = String.join(",", arr);
            String purposeNames = String.join(",", arr01);
            Long[] array = postMapper.selectPostListByProductId(sysProduct.getProductId()).toArray(new Long[0]);
            Long[] array01 = purposeMapper.selectPurposeListByProductId(sysProduct.getProductId()).toArray(new Long[0]);
            sysProduct.setPostIds(array);
            sysProduct.setPurposeIds(array01);
            sysProduct.setPostNames(postNames);
            sysProduct.setPurposeNames(purposeNames);
        });
        return sysProducts;
    }
}
